package com.zone.mybatis.binding;

import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.StrUtil;
import com.zone.mybatis.session.SqlSession;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @author: zongzi
 * @description: TODO
 * @date: 2023/12/17
 */
public class MapperRegistry {

    private final Map<Class<?>, MapperProxyFactory<?>> knowsMap = new HashMap<>();

    @SuppressWarnings("unchecked")
    public <T> T getMapper(Class<T> mapperInterface, SqlSession sqlSession) {
        if (!this.contains(mapperInterface)) {
            throw new RuntimeException("unknown mapper interface: " + mapperInterface.getName());
        }
        MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knowsMap.get(mapperInterface);
        return mapperProxyFactory.newInstance(sqlSession);
    }

    public void addMapper(Class<?> clazz) {
        if (clazz.isInterface()) {
            if (this.contains(clazz)) {
                throw new RuntimeException("repeat regis mapper clazz: " + clazz.getName());
            }
            MapperProxyFactory<?> mapperProxyFactory = new MapperProxyFactory<>(clazz);
            knowsMap.put(clazz, mapperProxyFactory);
        }
    }

    public boolean contains(Class<?> clazz) {
        return knowsMap.containsKey(clazz);
    }

    public void addMappers(String packageName) {
        if (StrUtil.isBlank(packageName)) {
            throw new RuntimeException("package name must not null packageName: " + packageName);
        }
        Set<Class<?>> clazzSet = ClassUtil.scanPackage(packageName);
        clazzSet.forEach(this::addMapper);
    }
}

